﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.IO;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.Graphics;

namespace Assignment1
{
    class Map
    {
        int width, height;
        private List<Tile> MapTiles;

        public Map()
        {
            MapTiles = Map.ReadMap("Content/map.txt");
            width = GetWidth();
            height = GetHeight();
            LinkTiles();           
        }

        public static List<Tile> ReadMap(string mapFile)
        {
            List<Tile> map = new List<Tile>();
            try
            {
                StreamReader reader = new StreamReader(mapFile);
                int x = 0;
                int y = 0;

                do
                {
                    int s = reader.Read();

                    if ((char)s == '\n')
                    {
                        x = 0;
                        y++;
                        continue;
                    }
                    else if ((char)s == ' ')
                    {
                        map.Add(new Tile
                        {
                            X = x,
                            Y = y,
                            TileType = TileType.OPEN
                        });               
                    }
                    else if ((char)s == 'X')
                    {
                        map.Add(new Tile
                        {
                            X = x,
                            Y = y,
                            TileType = TileType.SOLID
                        });
                    }
                    else if ((char)s == 'S')
                    {
                        map.Add(new Tile
                        {
                            X = x,
                            Y = y,
                            TileType = TileType.START
                        });
                    }
                    else if ((char)s == 'G')
                    {
                        map.Add(new Tile
                        {
                            X = x,
                            Y = y,
                            TileType = TileType.GOAL
                        });
                    }

                    x++;
                }
                while (!reader.EndOfStream);

                reader.Close();
                reader.Dispose();
            }
            catch (Exception e)
            {
                Console.WriteLine("Stream Reading Process Failed: {0}", e.ToString());                
            }

            return map;
        }

        // Setup the pointers to the grid's neighboring grids
        private void LinkTiles()
        {
            for (int i = 0; i < MapTiles.Count; i++)
            {
                // North
                if (i > width - 1)
                {
                    MapTiles[i].North = MapTiles[i - width];

                }

                // East
                if ((i + 1) % width != 0)
                {
                    MapTiles[i].East = MapTiles[i + 1];
                }

                // South
                if (i < MapTiles.Count() - width)
                {
                    MapTiles[i].South = MapTiles[i + width];
                }

                // West
                if (i % width != 0)
                {
                    MapTiles[i].West = MapTiles[i - 1];
                }
            }
        }

        public void Draw(SpriteBatch spriteBatch)
        {
            for (int i = 0; i < MapTiles.Count; ++i)
            {
                MapTiles[i].Draw(spriteBatch);
            }
        }

        //List<Tile> MapTileList
        //{
        //    get { return MapTiles; }
        //    set { MapTiles = value; }
        //}

        #region properties
        private int GetWidth()
        {
            int w = 0;
            for (int i = 0; i < MapTiles.Count; i++)
            {
                if (MapTiles[i].X > w)
                    w = MapTiles[i].X;
            }
            return w + 1;
        }

        private int GetHeight()
        {
            int h = 0;
            for (int i = 0; i < MapTiles.Count; i++)
            {
                if (MapTiles[i].X > h)
                    h = MapTiles[i].X;
            }
            return h + 1;
        }

        Tile GetStart()
        {
            for (int i = 0; i < MapTiles.Count; i++)
            {
                if (MapTiles[i].TileType == TileType.START)
                {
                    return MapTiles[i];
                }
            }
            return null;
        }

        Tile GetEnd()
        {
            for (int i = 0; i < MapTiles.Count; i++)
            {
                if (MapTiles[i].TileType == TileType.GOAL)
                {
                    return MapTiles[i];
                }
            }
            return null;
        }
        #endregion
    }
}
